
namespace ShoppingCart.DataAccess
{
	using System;
	using System.Collections.Generic;
	using System.Data;
    using Microsoft.Practices.EnterpriseLibrary.Data;
	using ShoppingCart.Business.Entity;

	/// <summary>
	/// Represents the DataAccess of ProductoData.
	/// </summary>
	public class ProductoData : Singleton<ProductoData>
	{
		#region Attributes

		private readonly Database BaseDatos = DatabaseFactory.CreateDatabase();

		#endregion

		#region Methods

		/// <summary>
		/// Selects all records from the Producto table by a foreign key.
		/// </summary>
		public IList<Producto> Listar()
		{
			var entidades = new List<Producto>();
			var comando = BaseDatos.GetStoredProcCommand("SelectAllProducto");

			using (var lector = BaseDatos.ExecuteReader(comando))
			{
				while (lector.Read())
				{
					entidades.Add(new Producto
					{
						IdProducto = lector.GetInt32(lector.GetOrdinal("IdProducto")),
						Nombre = lector.GetString(lector.GetOrdinal("Nombre")),
						Descripcion = lector.IsDBNull(lector.GetOrdinal("Descripcion"))? default(string) : lector.GetString(lector.GetOrdinal("Descripcion")),
						Icono = lector.IsDBNull(lector.GetOrdinal("Icono"))? default(string) : lector.GetString(lector.GetOrdinal("Icono")),
						Imagen = lector.IsDBNull(lector.GetOrdinal("Imagen"))? default(string) : lector.GetString(lector.GetOrdinal("Imagen")),
						Estado = lector.GetBoolean(lector.GetOrdinal("Estado")),
                        Linea = LineaData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdLinea")))
					});
				}
			}
			comando.Dispose();
			return entidades;
		}

		/// <summary>
		/// Selects all records from the Producto table by a foreign key.
		/// </summary>
		public Producto Obtener(int idProducto)
		{
			var producto = default(Producto);
			var comando = BaseDatos.GetStoredProcCommand("SelectProducto");

			BaseDatos.AddInParameter(comando, "IdProducto", DbType.Int32, idProducto);

			using (var lector = BaseDatos.ExecuteReader(comando))
			{
				while (lector.Read())
				{
					producto = new Producto
					{
						IdProducto = lector.GetInt32(lector.GetOrdinal("IdProducto")),
						Nombre = lector.GetString(lector.GetOrdinal("Nombre")),
						Descripcion = lector.IsDBNull(lector.GetOrdinal("Descripcion"))? default(string) : lector.GetString(lector.GetOrdinal("Descripcion")),
						Icono = lector.IsDBNull(lector.GetOrdinal("Icono"))? default(string) : lector.GetString(lector.GetOrdinal("Icono")),
						Imagen = lector.IsDBNull(lector.GetOrdinal("Imagen"))? default(string) : lector.GetString(lector.GetOrdinal("Imagen")),
						Estado = lector.GetBoolean(lector.GetOrdinal("Estado")),
                        Linea = LineaData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdLinea")))
					};
				}
			}
			comando.Dispose();
			return producto;
		}

		/// <summary>
		/// Saves a record to the Producto table.
		/// </summary>
		public int Agregar(Producto producto)
		{
			var comando = BaseDatos.GetStoredProcCommand("InsertProducto");
			BaseDatos.AddOutParameter(comando, "IdProducto", DbType.Int32, 4);
			BaseDatos.AddInParameter(comando, "Nombre", DbType.String, producto.Nombre);
			BaseDatos.AddInParameter(comando, "Descripcion", DbType.String, producto.Descripcion);
			BaseDatos.AddInParameter(comando, "IdLinea", DbType.Int32, producto.Linea.IdLinea);
			BaseDatos.AddInParameter(comando, "Icono", DbType.String, producto.Icono);
			BaseDatos.AddInParameter(comando, "Imagen", DbType.String, producto.Imagen);
			BaseDatos.AddInParameter(comando, "Estado", DbType.Boolean, producto.Estado);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Agregar Producto.");

			var valorDevuelto = (int)BaseDatos.GetParameterValue(comando, "IdProducto");;
			comando.Dispose();
			return valorDevuelto;
		}

		/// <summary>
		/// Updates a record in the Producto table.
		/// </summary>
		public bool Modificar(Producto producto)
		{
			var comando = BaseDatos.GetStoredProcCommand("UpdateProducto");
			BaseDatos.AddInParameter(comando, "IdProducto", DbType.Int32, producto.IdProducto);
			BaseDatos.AddInParameter(comando, "Nombre", DbType.String, producto.Nombre);
			BaseDatos.AddInParameter(comando, "Descripcion", DbType.String, producto.Descripcion);
			BaseDatos.AddInParameter(comando, "IdLinea", DbType.Int32, producto.Linea.IdLinea);
			BaseDatos.AddInParameter(comando, "Icono", DbType.String, producto.Icono);
			BaseDatos.AddInParameter(comando, "Imagen", DbType.String, producto.Imagen);
			BaseDatos.AddInParameter(comando, "Estado", DbType.Boolean, producto.Estado);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Modificar Producto.");

			comando.Dispose();
			return true;
		}

		/// <summary>
		/// Deletes a record from the Producto table by its primary key.
		/// </summary>
		public bool Eliminar(int idProducto)
		{
			var comando = BaseDatos.GetStoredProcCommand("DeleteProducto");
			BaseDatos.AddInParameter(comando, "IdProducto", DbType.Int32, idProducto);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Eliminar Producto.");
			comando.Dispose();
			return true;
		}

		/// <summary>
		/// Deletes a record from the Producto table by a foreign key.
		/// </summary>
		public void EliminarPorIdLinea(int idLinea)
		{
			var comando = BaseDatos.GetStoredProcCommand("DeleteProductoByIdLinea");
			BaseDatos.AddInParameter(comando, "IdLinea", DbType.Int32, idLinea);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Eliminar Producto.");
			comando.Dispose();
		}

		/// <summary>
		/// Selects all records from the Producto table by a foreign key.
		/// </summary>
		public IList<Producto> ListarPorIdLinea(int idLinea)
		{
			var entidades = new List<Producto>();
			var comando = BaseDatos.GetStoredProcCommand("SelectProductoByIdLinea");

			BaseDatos.AddInParameter(comando, "IdLinea", DbType.Int32, idLinea);

			using (var lector = BaseDatos.ExecuteReader(comando))
			{
				while (lector.Read())
				{
					entidades.Add(new Producto
					{
						IdProducto = lector.GetInt32(lector.GetOrdinal("IdProducto")),
						Nombre = lector.GetString(lector.GetOrdinal("Nombre")),
						Descripcion = lector.IsDBNull(lector.GetOrdinal("Descripcion"))? default(string) : lector.GetString(lector.GetOrdinal("Descripcion")),
						Icono = lector.IsDBNull(lector.GetOrdinal("Icono"))? default(string) : lector.GetString(lector.GetOrdinal("Icono")),
						Imagen = lector.IsDBNull(lector.GetOrdinal("Imagen"))? default(string) : lector.GetString(lector.GetOrdinal("Imagen")),
						Estado = lector.GetBoolean(lector.GetOrdinal("Estado")),
                        Linea = LineaData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdLinea")))
					});
				}
			}
			comando.Dispose();
			return entidades;
		}

		#endregion
	}
}
